local heg_description = [==[
# 国战简介

《三国杀·国战》是一款可以支持2\~12人(线上版4\~8人)同时参与的桌面卡牌游戏。在游戏中，每名玩家将甄选三国时代中包括魏国、蜀国、吴国、群雄在内的各位名将，组成自己的战斗团队，利用他们珠联璧合的组合技能发起进攻，消灭其他各方势力，赢得最终的胜利。

## 准备游戏

**挑选武将：**

发给每位玩家若干张张武将牌，选出两张势力相同的武将牌并背面朝上放置，称为“暗置”（参考段落“明置和暗置”）。

靠近体力牌的武将视为副将，另一个视为主将。

游戏中，每名玩家扮演的角色由两张武将牌组成。

**分发体力牌：**

每位玩家拿取一张体力牌，翻到对应体力上限的一面，放置在武将牌旁边。体力上限为两张武将牌上的完整阴阳鱼的数量之和。两个单独的阴阳鱼可以组成一个完整的阴阳鱼。

注：**当一名角色的两张武将牌第一次均明置时，若其武将牌上有单独的阴阳鱼没有组成1 点体力，则其获得一枚“阴阳鱼”**（参见段落“标记牌”）。例如，司马懿1.5阴阳鱼，张辽2阴阳鱼，合计3.5阴阳鱼，体力上限为3，获得一枚“阴阳鱼”。

扣减体力时，用主将挡住扣减的体力，露出当前体力值。

## 进行游戏

随机选择一名玩家作为起始玩家。由该玩家开始，按逆时针方向以回合的方式进行。即每名玩家有一个自己的回合，一名玩家的回合结束后， 右边玩家的回合开始，依次轮流进行。

每个玩家的回合可以分为六个阶段：

准备阶段 -> 判定阶段 -> 摸牌阶段 -> 出牌阶段 -> 弃牌阶段 -> 结束阶段

**准备阶段：**

有些技能可以在此阶段发动。你的暗置的武将牌也可于此阶段明置。

**判定阶段：**

若你的面前横置着延时类锦囊，你必须依次对这些延时类锦囊进行判定。若有多张延时类锦囊，先判定最后放置的那张，然后以此类推。

**摸牌阶段：**

你从牌堆顶摸两张牌。（如无特别说明，“摸……张牌”就是从牌堆顶摸牌）

**出牌阶段：**

你可以使用任意张牌，但必须遵守以下两条规则：

1. 每个出牌阶段仅限使用一次【杀】。
2. 任何一名角色面前的判定区里不能放有两张同名的牌。

每使用一张牌，即执行该牌之效果，详见“游戏牌详解”。如无特殊说明，游戏牌在使用后均需置入弃牌堆。

**弃牌阶段：**

在出牌阶段中，不想出或没法出牌时，就进入弃牌阶段。此时检查你的手牌数是否超出你当前的体力值( 你的手牌上限等于你当前的体力值)， 每超出一张，须弃置一张手牌。

**结束阶段：**

有些技能可以在此阶段发动。


## 角色死亡

当一名角色的体力降到0 时，即进入濒死状态，除非该角色在此时使用【酒】，或有角色使用【桃】来挽救该角色，否则该角色死亡。

死亡的角色明置其武将牌，弃置该角色所有牌及其判定区里的牌，然后执行奖惩。

奖惩方式：

1. **已经确定势力的角色杀死相同势力的角色须弃置所有手牌和装备区的牌**；
2. **已经确定势力的角色杀死不同势力的角色，摸等同于该势力人数（包括刚刚杀死的角色）张牌**；
3. 特别地，野心家击杀奖励为摸三张牌。

例：“蜀”势力角色杀死了一名“魏”势力角色，此时还有其他两名“魏”势力角色存活，则该“蜀”势力角色摸三张牌。

注：若被杀死的角色还没有明置武将牌（即没确定势力），则须明置所有武将牌，验明势力。 没有势力的角色（即武将牌没有明置的角色）杀死其他角色没有奖惩。

## 胜负结算

玩家的游戏目标与势力有关：**消灭所有与自己不同势力的角色**。

特殊的：野心家需要消灭所有其他角色。

当全场所有角色均确定势力后, 才可以进行胜利条件的判断:
当全场只剩下一种势力存活时, 该势力的角色获胜( 没有确定势力的角色无法取得游戏胜利, 即使与存活的其他角色为同一势力)。

## 暗将规则

**处于暗置状态的武将牌没有任何武将技能、性别以及势力**。当暗置的武将牌发动技能时，将武将牌明置，然后发动相应的技能。

一般地，**暗置的武将牌只有两个时机可以将武将牌明置：1. 准备阶段开始时；2. 发动武将牌的技能时。** 

例：郭嘉、司马懿等，受到伤害后发动技能时明置武将牌；
马超、黄忠等，使用【杀】指定一名角色为目标后，发动技能并明置武将牌；
孙权、甘宁等，在出牌阶段发动技能时明置武将牌；

（在网杀中，你需要“预亮”某些触发技，即点击技能到“预亮”状态，来让系统在相应的时机询问你是否发动技能亮将，如预亮郭嘉、马超等的遗计、铁骑。不“预亮”的技能不会询问。）

另外，**拥有锁定技的武将，可以在出牌阶段明置。** 例如：有咆哮的张飞、有马术的马超。

**全场游戏第一个明置武将的角色获得一枚“先驱”标记（参见段落“标记牌”）。

没有明置武将牌的角色没有性别，任何与性别有关的技能和武器效果均不能对其发动。

有一张武将牌明置时，角色性别与明置的武将牌相同。当一名角色的两张武将牌均亮明后，性别与主将的武将牌相同。

没有明置武将牌的角色没有势力，明置一张武将牌后确定势力：与武将牌左上角所示的势力相同，或成为野心家。野心家用“野心家牌”表示。（参见下一段“野心家规则”）。

野心家规则：

**当一名角色明置武将牌确定势力时，若该势力的角色超过了游戏总玩家数的一半，则他成为野心家**，拿取一张野心家牌表示。若之后仍然有该势力的角色明置武将牌，均视为野心家。**野心家为单独的一种势力**，与其他角色的势力均不同。他（们）需要杀死所有其他角色，成为唯一的存活者。

注意：野心家与野心家之间也是不同势力。

例：

★ 6 人、7 人游戏时，当出现第四名同势力角色时，该角色及之后明置的该势力角色均成为野心家。

★ 8 人、9 人游戏时，当出现第五名同势力角色时，该角色及之后明置的该势力角色均成为野心家。

## 珠联璧合

珠联璧合表示了部分武将之间的特殊联系。一般是夫妻、挚友等，如刘备-关羽，周瑜-小乔。

武将牌中下方的其他武将姓名表示了可以和此武将牌形成珠联璧合的其他武将。

**若你选择的两张武将牌形成珠联璧合，则在第一次两张武将牌均明置时，获得一枚“珠联璧合”**（参见段落“标记牌”）。

## 标记牌

**珠联璧合**：出牌阶段，你可弃一枚“珠联璧合”，摸两张牌；你可弃一枚“珠联璧合”，视为使用【桃】。

**阴阳鱼**：出牌阶段，你可弃一枚“阴阳鱼”，摸一张牌；弃牌阶段开始时，你可弃一枚“阴阳鱼”，此回合手牌上限+2。

**先驱**：出牌阶段，你可弃一枚“先驱”，将手牌摸至4张，观看一名其他角色的一张暗置武将牌。

## 鏖战

当游戏中仅剩4名或更少角色时（7人以下游戏时为3名或更少），若此时全场没有超过一名势力相同的角色，则从一个新的回合开始，游戏进入鏖战模式。

鏖战模式下，所有的【桃】只能当【杀】或【闪】使用或打出，不能用于回复体力。

# 君临天下和势备篇补充规则和术语

## 大小势力 （势备篇）

**大势力**：人数最多且数量不小于2的势力。

**小势力**：若大势力存在，除大势力以外的其他势力。

**大势力角色**：势力为大势力的角色。

**小势力角色**：若大势力角色存在，不为大势力角色的角色。

没有大势力，就不可能有小势力、大势力角色、小势力角色。反之，有大势力，不一定有小势力。

小势力角色还包括未确定势力的角色。即势力为小势力的角色一定是小势力角色，而小势力角色不一定是势力为小势力的角色。

## 合纵 （势备篇）

某些牌上标有“合”标记。

每名角色的出牌阶段限一次，可以选择一项：
1.若你已确定势力，你可以将手牌中有“合”标记的至多三张牌交给与你势力不同的一名角色，摸等量的牌。
2.你可以将手牌中有“合”标记的至多三张牌交给未确定势力的一名角色。

即，出限一、限三张、摸等量。给明将摸牌，给暗将不摸；暗将不能给明将。

## 阵法、围攻、队列、主/副将技 （君临天下·阵）

**阵法技**：在全场存活角色数为4或更多时锁定生效的技能。拥有阵法技的角色可在其准备阶段开始时或出牌阶段发起“阵法召唤”。

**阵法召唤**：由拥有阵法技的角色发起，未确定势力、明置后将会满足此阵法技条件的角色均可明置其一张（满足条件的）武将牌，响应阵法召唤。

**围攻**：一名角色的上家和下家为两名势力相同的角色(且与该角色势力不同)时，该角色被“围攻”，成为“被围攻角色”；该角色的上家和下家成为“围攻角色”；该“围攻角色”和“被围攻角色”处于同一“围攻关系”。

**队列**：连续相邻的若干名(至少2名)势力相同的角色称为同一“队列”。

**主将技**：此武将牌为主将时才能使用的技能。

**副将技**：此武将牌为副武将才能使用的技能。

## 移除 （君临天下·势）

**移除**：将被移除的武将牌置入武将牌堆。被移除武将牌的角色用一张“士兵牌”来代替被移除的武将牌，“士兵牌”的性别、势力与被移除的武将牌相同，但没有技能，该角色没有“士兵牌”所占据的主将/副将。

## 变更 （君临天下·变）

**变更**：（线下）从武将牌堆中连续亮出武将牌，直到亮出一张势力相同的武将牌。将此武将牌作为新的副将（若原先有副将，将副将的原武将牌置入武将牌堆）。每局游戏限一次。

（线上则为从提供的三个同势力武将中选择一个）

## 军令 （君临天下·权）

**军令**：有些技能可以发起军令，发起军令分为（发起者）抽取选择军令和（执行者）询问执行军令。

发起军令的角色随机获得两张军令牌，然后选择其中一张，交给执行军令的角色。

执行军令的角色选择是否执行该“军令”。如果执行，该军令牌的效果生效。

6张军令牌：

军令一：对发起者指定的角色造成1点伤害；

军令二：摸一张牌，然后交给发起者两张牌；

军令三：失去1点体力；

军令四：本回合不能使用或打出手牌且所有非锁定技失效；

军令五：叠置，本回合不能回复体力；

军令六：选择一张手牌和一张装备区里的牌，弃置其余的牌。

## 君主规则 （君临天下）

武将牌上的势力名称为“君”的武将为该势力君主武将。（君刘备、君张角、君孙权、君曹操）

玩家将对应的普通武将设置为主将，在第一个回合开始亮将时，可以亮出主将并替换为对应的君主武将。

（其他时点亮将均不能变身君主武将。）

君主武将牌不可被暗置。君主武将和所有本势力武将均有“珠联璧合”的关系。

君主武将牌明置时，所有与此君主势力相同的野心家角色恢复其原有势力，在君主武将存活时，所有与君主势力相同的角色均不会成为野心家。

某势力的君主死后，其他与君主势力相同的角色均成为野心家。

]==]

local H = require "packages/hegemony/util"

local heg

---@class HegLogic: GameLogic
local HegLogic = {}

function HegLogic:assignRoles()
  local room = self.room
  for _, p in ipairs(room.players) do
    p.role_shown = false
    p.role = "hidden"
    room:broadcastProperty(p, "role")
  end

  -- for adjustSeats
  room.players[1].role = "lord"
end

function HegLogic:prepareDrawPile()
  local room = self.room
  local allCardIds = Fk:getAllCardIds()

  for i = #allCardIds, 1, -1 do
    local card = Fk:getCardById(allCardIds[i])
    if card.is_derived or (H.convertCards[card.name] and table.find(H.convertCards[card.name], function(c)
        return table.contains(allCardIds, c.id)
      end)) then
      local id = allCardIds[i]
      table.removeOne(allCardIds, id)
      table.insert(room.void, id)
      room:setCardArea(id, Card.Void, nil)
    end
    if table.contains(H.allianceCards, card) then
      room:setCardMark(card, "@@alliance", 1)
    end
  end

  table.shuffle(allCardIds)
  room.draw_pile = allCardIds
  for _, id in ipairs(room.draw_pile) do
    room:setCardArea(id, Card.DrawPile, nil)
  end
end

function HegLogic:chooseGenerals()
  local room = self.room
  local generalNum = math.max(room.settings.generalNum, 5)
  room:doBroadcastNotify("ShowToast", Fk:translate("#HegInitialNotice"))

  local lord = room:getLord()
  room.current = lord
  lord.role = "hidden"

  local players = room.players
  local generals = room:getNGenerals(#players * generalNum) -- Fk:getGeneralsRandomly
  table.shuffle(generals)
  for k, p in ipairs(players) do
    -- UI
    p:setMark("@seat", "seat#" .. tostring(p.seat))
    p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", "seat#" .. tostring(p.seat)})

    -- local arg = { map = table.map }
    local arg = table.slice(generals, (k - 1) * generalNum + 1, k * generalNum + 1)
    table.sort(arg, function(a, b) return Fk.generals[a].kingdom > Fk.generals[b].kingdom end)

    for idx, _ in ipairs(arg) do
      local g = Fk.generals[arg[idx]]
      local g2 = Fk.generals[arg[idx + 1]]
      if (g.kingdom == g2.kingdom and g.kingdom ~= "wild") or (g.kingdom == "wild" and g2.kingdom ~= "wild") or (g.kingdom == "jinh" and g2.kingdom ~= "god") or (g.kingdom ~= "god" and g2.kingdom == "jinh") or
        (g.subkingdom ~= nil and g.subkingdom == g2.subkingdom) or g.kingdom == g2.subkingdom or g.subkingdom == g2.kingdom then
          p.default_reply = arg[idx] .. "+" .. arg[idx + 1]
          break
      end
    end
    p.request_data = json.encode{ arg, 2, false, true }
  end
  room:notifyMoveFocus(players, "AskForGeneral")
  room:doBroadcastRequest("AskForGeneral", players)

  local selected = {}
  for _, p in ipairs(players) do
    local general, deputy
    if p.general == "" and p.reply_ready then
      local general_ret = json.decode(p.client_reply)
      general = general_ret[1]
      deputy = general_ret[2]
      room:setPlayerGeneral(p, general, true)
      room:setDeputyGeneral(p, deputy)
    else
      local general_ret = string.split(p.default_reply, "+")
      general = general_ret[1]
      deputy = general_ret[2]
    end
    table.insertTableIfNeed(selected, {general, deputy})

--[[ -- FIXME
    p:setMark("__heg_general", general) 
    p:setMark("__heg_deputy", deputy)
    p:doNotify("SetPlayerMark", json.encode{ p.id, "__heg_general", general})
    p:doNotify("SetPlayerMark", json.encode{ p.id, "__heg_deputy", deputy})
]]

    room:setPlayerMark(p, "__heg_general", general)
    room:setPlayerMark(p, "__heg_deputy", deputy)

    room:setPlayerGeneral(p, "anjiang", true)
    room:setDeputyGeneral(p, "anjiang")

    p.default_reply = ""
  end

  generals = table.filter(generals, function(g) return not table.contains(selected, g) end)
  room:returnToGeneralPile(generals)
  for _, p in ipairs(players) do
    local allKingdoms = {"wei", "shu", "wu", "qun"}
    local curGeneral = Fk.generals[p:getMark("__heg_general")]
    local kingdoms = {curGeneral.kingdom, curGeneral.subkingdom}
    curGeneral = Fk.generals[p:getMark("__heg_deputy")]
    if kingdoms[1] == ("wild" or "jinh") then
      kingdoms = {curGeneral.kingdom, curGeneral.subkingdom}
      room:setPlayerMark(p, "__heg_wild", 1)
    else
      kingdoms = table.filter(kingdoms, function(k) return curGeneral.kingdom == k or curGeneral.subkingdom == k end)
    end
    p.default_reply = kingdoms[1]
    local data = json.encode({ kingdoms, allKingdoms, "AskForKingdom", "#ChooseHegInitialKingdom" })
    p.request_data = data
  end
  room:notifyMoveFocus(players, "AskForKingdom")
  room:doBroadcastRequest("AskForChoice", players)
  for _, p in ipairs(players) do
    local kingdomChosen
    if p.reply_ready then
      kingdomChosen = p.client_reply
    else
      kingdomChosen = p.default_reply
    end
    room:setPlayerMark(p, "__heg_kingdom", kingdomChosen)
    room:setPlayerMark(p, "__heg_init_kingdom", kingdomChosen)
    p.default_reply = ""
    -- p.kingdom = kingdomChosen
    --room:notifyProperty(p, p, "kingdom")
  end
end

function HegLogic:broadcastGeneral()
  local room = self.room
  local players = room.players

  for _, p in ipairs(players) do
    p:setMark("@seat", 0)
    p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", 0})

    assert(p.general ~= "")
    local general = Fk.generals[p:getMark("__heg_general")]
    local deputy = Fk.generals[p:getMark("__heg_deputy")]
    local dmaxHp = deputy.maxHp + deputy.deputyMaxHpAdjustedValue
    local gmaxHp = general.maxHp + general.mainMaxHpAdjustedValue
    p.maxHp = (dmaxHp + gmaxHp) // 2
    -- p.hp = math.floor((deputy.hp + general.hp) / 2)
    p.hp = p.maxHp
    -- p.shield = math.min(general.shield + deputy.shield, 5)
    p.shield = 0
    -- TODO: setup AI here

    room:broadcastProperty(p, "general")
    room:broadcastProperty(p, "deputyGeneral")
    room:broadcastProperty(p, "maxHp")
    room:broadcastProperty(p, "hp")
    room:broadcastProperty(p, "shield")

    p.role = p:getMark("__heg_wild") == 1 and "wild" or p:getMark("__heg_kingdom") -- general.kingdom -- 为了死亡时log有势力提示

    if (dmaxHp + gmaxHp) % 2 == 1 then
      p:setMark("HalfMaxHpLeft", 1)
      p:doNotify("SetPlayerMark", json.encode{ p.id, "HalfMaxHpLeft", 1})
    end
    if general:isCompanionWith(deputy) then
      p:setMark("CompanionEffect", 1)
      p:doNotify("SetPlayerMark", json.encode{ p.id, "CompanionEffect", 1})
    end
  end
end

local function addHegSkill(player, skill, room)
  if skill.frequency == Skill.Compulsory then
    player:addFakeSkill("reveal_skill&")
  end
  player:addFakeSkill(skill)
  local toget = {table.unpack(skill.related_skills)}
  table.insert(toget, skill)
  for _, s in ipairs(toget) do
    if s:isInstanceOf(TriggerSkill) then
      room.logic:addTriggerSkill(s)
    end
  end
end

function HegLogic:attachSkillToPlayers()
  local room = self.room
  local players = room.players

  room:handleAddLoseSkills(players[1], "#_heg_invalid", nil, false, true)

  for _, p in ipairs(room.alive_players) do
    local general = Fk.generals[p:getMark("__heg_general")]
    local skills = table.connect(general.skills, table.map(general.other_skills, Util.Name2SkillMapper))
    for _, s in ipairs(skills) do
      if s.relate_to_place ~= "d" then
        addHegSkill(p, s, room)
      end
    end

    local deputy = Fk.generals[p:getMark("__heg_deputy")]
    if deputy then
      skills = table.connect(deputy.skills, table.map(deputy.other_skills, Util.Name2SkillMapper))
      for _, s in ipairs(skills) do
        if s.relate_to_place ~= "m" then
          addHegSkill(p, s, room)
        end
      end
    end
  end

  room:setTag("SkipNormalDeathProcess", true)
  room:doBroadcastNotify("ShowToast", Fk:translate("#HegInitialNotice"))
end

local heg_getlogic = function()
  local h = GameLogic:subclass("HegLogic")
  for k, v in pairs(HegLogic) do
    h[k] = v
  end
  return h
end

local heg_invalid = fk.CreateInvaliditySkill{
  name = "#_heg_invalid",
  invalidity_func = function(self, player, skill)
  end,
}

local wildKingdoms = {"heg_qin", "heg_qi", "heg_chu", "heg_yan", "heg_zhao", "heg_hanr", "heg_xia", "heg_shang", "heg_zhou", "heg_liang"} -- hanr 韩
local kingdomMapper = { ["ld__zhonghui"] = "heg_han", ["ld__simazhao"] = "heg_jin", ["ld__gongsunyuan"] = "heg_yan", ["ld__sunchen"] = "heg_chu" }
local function wildChooseKingdom(room, player, generalName)
  local choice
  local all_choices = table.clone(wildKingdoms)
  local choices = table.clone(all_choices)
  for _, p in ipairs(room.players) do
    table.removeOne(choices, p.role)
  end
  if player.general == generalName and kingdomMapper[generalName] and kingdomMapper[generalName] ~= player.role then -- 野心家钦定
    if table.contains(choices, kingdomMapper[generalName]) then
      choice = kingdomMapper[generalName]
    else
      choice = room:askForChoice(player, choices, "#heg_rule", "#wild-choose", false, all_choices)
    end
  elseif table.contains({"wei", "shu", "wu", "qun", "jin", "unknown", "hidden"}, player.role) then
    choice = room:askForChoice(player, choices, "#heg_rule", "#wild-choose", false, all_choices)
  end
  if choice then
    player.role = choice
    player.role_shown = true
    room:broadcastProperty(player, "role")
    room:sendLog{
      type = "#WildChooseKingdom",
      from = player.id,
      arg = choice,
      arg2 = "wild",
    }
  end
end  

local function AskForBuildCountry(room, player, generalName, isActive)
  if player.general == generalName and kingdomMapper[generalName] then
    -- local choices = {"heg_rule_join_country:"..generalName, "Cancel"}
    local choices = {"heg_rule_join_country:"..player.id.."::"..kingdomMapper[generalName], "Cancel"}
    local targets = table.map(room.alive_players, Util.IdMapper)
    room:sortPlayersByAction(targets)
    for _, pid in ipairs(targets) do
      local p = room:getPlayerById(pid)
      if p:getMark("__heg_join_wild") == 0 and p.kingdom ~= "wild" and not string.find(p.general, "lord")
       and ((isActive == true and p.general ~= "anjiang") or (isActive == false and p.deputyGeneral.kingdom == player.deputyGeneral.kingdom))then
        local choice = room:askForChoice(p, choices, "#heg_rule", "#wild_join-choose")
        if choice ~= "Cancel" then
          p.role = kingdomMapper[generalName]
          player.role_shown = true
          room:broadcastProperty(p, "role")
          room:sendLog{
            type = "#WildChooseKingdom",
            from = p.id,
            arg = kingdomMapper[generalName],
            arg2 = "wild",
          }
          room:setPlayerProperty(p, "kingdom", "wild")
          room:setPlayerMark(p, "__heg_join_wild", 1)
          room:setPlayerMark(player, "__heg_construct_wild", 1)
          room:setPlayerMark(player, "_wild_gained", 1)
          room:sendLog{
            type = "#SuccessBuildCountry",
            from = player.id,
            arg = kingdomMapper[generalName],
            arg2 = p.general
          }
          if p.hp < p.maxHp then
            room:recover({
              who = p,
              num = 1,
              recoverBy = player,
              skillName = "#heg_rule",
            })
          end
          if p:getHandcardNum() < 4 then
            p:drawCards(4 - p:getHandcardNum(), "#heg_rule")
          end
          break
        end
      end
    end
  end
end

local heg_rule = fk.CreateTriggerSkill{
  name = "#heg_rule",
  priority = 0.001,
  events = {fk.BeforeTurnStart, fk.TurnStart, fk.GameOverJudge, fk.Deathed, fk.GeneralRevealed, fk.EventPhaseChanging, fk.GeneralShown},
  can_trigger = function(self, event, target, player, data)
    return target == player
  end,
  on_trigger = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeTurnStart then
      -- 鏖战
      if #room.alive_players < (#room.players > 6 and 5 or 4) and not room:getTag("BattleRoyalMode") then
        local ret = true
        for _, v in pairs(H.getKingdomPlayersNum(room)) do
          if v and v > 1 then
            ret = false
            break
          end
        end
        if ret then
          room:doBroadcastNotify("ShowToast", Fk:translate("#EnterBattleRoyalMode"))
          room:sendLog{
            type = "#EnterBattleRoyalModeLog",
          }
          room:setTag("BattleRoyalMode", true)
          room:setBanner("@[:]BattleRoyalDummy", "BattleRoyalMode")
          for _, p in ipairs(room.alive_players) do
            -- p:addFakeSkill("battle_royal&")
            -- p:addFakeSkill("battle_royal_prohibit&")
            room:handleAddLoseSkills(p, "battle_royal&", nil, false, true)
          end
        end
      end
    elseif event == fk.TurnStart then
      H.askForRevealGenerals(room, player, self.name, true, true, true, true, true) -- lord
    elseif event == fk.GameOverJudge then
      -- if table.every(room.alive_players, function (p) return H.compareKingdomWith(p, player) end) then
      player:revealGeneral(false)
      player:revealGeneral(true)
      local winner = Fk.game_modes[room.settings.gameMode]:getWinner(player)
      if winner ~= "" then
        for _, ps in ipairs(room.alive_players) do
          -- 先检测并询问主将是不是野人
          if ps.general == "anjiang" then 
            -- 是野人则强制亮出来
            if ps:getMark("__heg_wild") == 1 then
              ps:revealGeneral(false)
            end
          end
        end
        -- 强制亮完野人后检测场上有没有野人
        if table.find(room.alive_players, function(p) return p:getMark("__heg_wild") == 1 end) then
          --有野人则依次询问拉拢
          for _, p in ipairs(room.alive_players) do
            if p:getMark("__heg_wild") == 1 then 
              wildChooseKingdom(room, p, p.general.name)
              AskForBuildCountry(room, p, p.general.name, false)
            end
          end
        end
        -- 然后判断场上所有人势力是否相同
        local _kingdom2 = {}
        for _, p in ipairs(room.alive_players) do
          if not table.contains(_kingdom2, p.kingdom) then
            table.insert(_kingdom2, p.kingdom)
          end
        end
        if #_kingdom2 == 1 then
          -- 若所有人势力相同则全部亮将
          for _, p in ipairs(room.alive_players) do
            if p.general == "anjiang" then p:revealGeneral(false) end
            if p.deputyGeneral == "anjiang" then p:revealGeneral(true) end
          end
          room:gameOver(winner)
          return true
        end
      end
      room:setTag("SkipGameRule", true)
    elseif event == fk.Deathed then
      local damage = data.damage
      if damage and damage.from then
        local killer = damage.from
        if killer.kingdom ~= "unknown" and not killer.dead then
          if killer.kingdom == "wild" then
            -- 因为建国，修改奖惩
            -- 如果还没建国
            if killer:getMark("__heg_construct_wild") == 0 and killer:getMark("__heg_join_wild") == 0 then
              killer:drawCards(3, "kill")
            else
              -- 如果已经建国
              if H.compareKingdomWith(killer, player) then
                if not (room.logic:getCurrentEvent():findParent(GameEvent.Death, true).extra_data or {}).ignorePunishment then
                  killer:throwAllCards("he")
                end
              else
                -- 这里改为比较role，野人和野人之间的势力不同 （傻逼）
                killer:drawCards( #table.filter(room.alive_players, function(p)
                  return H.compareKingdomWith(p, player)
                end) + 1, "kill")
              end
            end
          elseif H.compareKingdomWith(killer, player) then
            if not (room.logic:getCurrentEvent():findParent(GameEvent.Death, true).extra_data or {}).ignorePunishment then
              killer:throwAllCards("he")
            end
          else
            -- 因为建国，修改奖惩，杀了野人不一定只摸一，这里也改为比较role
            killer:drawCards( #table.filter(room.alive_players, function(p)
              return H.compareKingdomWith(p, player)
            end) + 1, "kill")
          end
        end
      end
      if string.find(player.general, "lord") then
        local players = table.map(table.filter(room.players, function(p) return
          (p:getMark("__heg_kingdom") == player.kingdom or (p.dead and p.kingdom == player.kingdom)) and p ~= player and p.kingdom ~= "wild"
        end), Util.IdMapper)
        room:sortPlayersByAction(players)
        for _, pid in ipairs(players) do
          local p = room:getPlayerById(pid)
          local oldKingdom = p.kingdom
          room:setPlayerMark(p, "__heg_kingdom", "wild")
          if oldKingdom ~= "unknown" then
            room:setPlayerProperty(p, "kingdom", "wild")
            if not p.dead then wildChooseKingdom(room, p, p.general) end
          end
        end
      end
    elseif event == fk.GeneralRevealed then
      for _, general_name in pairs(data) do
        if room:getTag("TheFirstToShowRewarded") == player.id and player:getMark("_vanguard_gained") == 0 then
          room:setPlayerMark(player, "_vanguard_gained", 1)
          H.addHegMark(room, player, "vanguard")
        end
        if player:getMark("hasShownMainGeneral") == 1 and Fk.generals[general_name].kingdom == "wild" and player:getMark("_wild_gained") == 0 then
          room:setPlayerMark(player, "_wild_gained", 1)
          H.addHegMark(room, player, "wild")
        end
        if player.general == "anjiang" or player.deputyGeneral == "anjiang" then return false end
        if player:getMark("HalfMaxHpLeft") > 0 then
          room:setPlayerMark(player, "HalfMaxHpLeft", 0)
          H.addHegMark(room, player, "yinyangfish")
        end
        if player:getMark("CompanionEffect") > 0 then
          room:setPlayerMark(player, "CompanionEffect", 0)
          H.addHegMark(room, player, "companion")
        end
      end
    elseif event == fk.EventPhaseChanging then
      if data.to == Player.Play then
        player:addFakeSkill("alliance&")
      elseif data.from == Player.Play then
        player:loseFakeSkill("alliance&")
      end
    elseif event == fk.GeneralShown then
      if not room:getTag("TheFirstToShowRewarded") then
        room:setTag("TheFirstToShowRewarded", player.id)
      end
      local general_name = data["m"] or data["d"]
      if general_name and string.find(general_name, "lord") then
        local kingdom = player:getMark("__heg_kingdom")
        for _, p in ipairs(room.players) do
          if p:getMark("__heg_kingdom") == kingdom and p.kingdom == "wild" and p:getMark("__heg_wild") == 0 then
            room:setPlayerProperty(p, "kingdom", kingdom)
            p.role_shown = false
            room:setPlayerProperty(p, "role", kingdom)
          end
        end
      end
      if player.kingdom == "wild" and not player.dead then
        wildChooseKingdom(room, player, general_name)
        -- 野人亮出来的时候询问拉拢
        AskForBuildCountry(room, player, general_name, true)
      elseif player:getMark("__heg_join_wild") == 0 and player:getMark("__heg_construct_wild") == 0 then
        player.role = player.kingdom
      end

      for _, v in pairs(H.getKingdomPlayersNum(room)) do
        if v == #room.alive_players then
          local winner = Fk.game_modes[room.settings.gameMode]:getWinner(player)
          for _, p in ipairs(room.alive_players) do
            -- 先检测并询问主将是不是野人
            if p.general == "anjiang" then 
              -- 是野人则强制亮出来
              if p:getMark("__heg_wild") == 1 then
                p:revealGeneral(false)
              end
            end
          end
          -- 强制亮完野人后检测场上有没有野人
          if table.find(room.alive_players, function(p) return p:getMark("__heg_wild") == 1 end) then
            --有野人则依次询问拉拢
            for _, p in ipairs(room.alive_players) do
              if p:getMark("__heg_wild") == 1 then 
                wildChooseKingdom(room, p, p.general.name)
                AskForBuildCountry(room, p, p.general.name, false)
              end
            end
          end
          -- 然后判断场上所有人势力是否相同
          if table.every(room.alive_players, function(p) return H.compareKingdomWith(p, player) end) then
            -- 若所有人势力相同则全部亮将
            for _, p in ipairs(room.alive_players) do
              if p.general == "anjiang" then p:revealGeneral(false) end
        
              if p.deputyGeneral == "anjiang" then p:revealGeneral(true) end
            end
            room:gameOver(winner)
            return true
          end
        else
          break
        end
      end
      if player:getMark("hasShownMainGeneral") == 0 and data["m"] then -- 首次亮主将
        room:setPlayerMark(player, "hasShownMainGeneral", 1)
      end
    end
  end,
}
Fk:addSkill(heg_rule)

heg = fk.CreateGameMode{
  name = "zhonger_heg_mode",
  minPlayer = 2,
  maxPlayer = 10,
  rule = heg_rule,
  logic = heg_getlogic,
  is_counted = function(self, room)
    return #room.players >= 6
  end,

  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(room.alive_players, function(p)
      return not p.surrendered
    end)
    if #alive == 1 then
      local p = alive[1] ---@type ServerPlayer
      p:revealGeneral(false)
      p:revealGeneral(true)
      return p.role
    end

    local winner -- = alive[1]
    for _, p in ipairs(alive) do
      if p.kingdom ~= "unknown" then
        winner = p
        break
      end
    end
    if not winner then return "" end
    local kingdom = H.getKingdom(winner)
    local i = H.getKingdomPlayersNum(room, true)[kingdom]
    for _, p in ipairs(alive) do
      if not H.compareExpectedKingdomWith(p, winner) then
        return ""
      end
      if p.kingdom == "unknown" then
        i = i + 1
      end
    end
    if i > #room.players // 2 and not H.getHegLord(room, winner) then return "" end
    return kingdom
  end,
  surrender_func = function(self, playedTime)
    local winner
    local kingdomCheck = true
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      -- 场上有未明置的主将时不能投降
      if p.general == "anjiang" then
        kingdomCheck = false
        break
      end
      if p ~= Self then
        if not winner then
          winner = p
        elseif not H.compareKingdomWith(winner, p) then
          kingdomCheck = false
          break
        end
      end
    end
    return { { text = "heg: besieged on all sides", passed = kingdomCheck } }
  end,
}

local notice = "此模式为<b><font color='purple'>经典国战模式</font></b>"

Fk:loadTranslationTable{
  ["zhonger_heg_mode"] = "经典国战模式",
  [":zhonger_heg_mode"] = heg_description,
  ["#ChooseHegInitialKingdom"] = "国战规则：选择你的初始势力",
  ["wild"] = "野心家",
  ["#heg_rule"] = "国战规则",
  ["revealAll"] = "全部明置",
  ["#EnterBattleRoyalMode"] = "游戏进入 <font color=\"red\"><b>鏖战模式</b></font>，所有的【<font color=\"#3598E8\"><b>桃</b></font>】"..
  "只能当【<font color=\"#3598E8\"><b>杀</b></font>】或【<font color=\"#3598E8\"><b>闪</b></font>】使用或打出，不能用于回复体力",
  ["#EnterBattleRoyalModeLog"] = "游戏进入 <font color=\"#CC3131\"><b>鏖战模式</b></font>",
  ["@[:]BattleRoyalDummy"] = "", -- 额
  ["BattleRoyalMode"] = "鏖战模式",
  [":BattleRoyalMode"] = "所有的【<font color=\"#3598E8\"><b>桃</b></font>】"..
  "只能当【<font color=\"#3598E8\"><b>杀</b></font>】或【<font color=\"#3598E8\"><b>闪</b></font>】使用或打出，不能用于回复体力",
  ["#wild-choose"] = "野心家建国：选择你要成为的势力！",
  ["heg_qin"] = "秦",
  ["heg_qi"] = "齐",
  ["heg_chu"] = "楚",
  ["heg_yan"] = "燕",
  ["heg_zhao"] = "赵",
  ["heg_hanr"] = "韩",
  ["heg_xia"] = "夏",
  ["heg_shang"] = "商",
  ["heg_zhou"] = "周",
  ["heg_liang"] = "凉",
  ["#WildChooseKingdom"] = "%from 成为 %arg2 ，选择了势力 %arg",
  ["heg: besieged on all sides"] = "四面楚歌，被同一势力围观",
  ["@@alliance"] = "合",
  ["@@alliance-inhand"] = "合",
  ["@@alliance-inhand-turn"] = "合",
  ["@seat"] = "",

  ["#SuccessBuildCountry"] = "%from 成功建立国家，国号 %arg ，队友是 %arg2",
  ["heg_rule_join_country"] = "加入 %src 的阵营 %arg",

  ["#HegInitialNotice"] = notice
}

return heg